/**
 * 数据扁平化
 */

//  泛型 K extends keyof 泛型 T

type Worker = {
  custname: string;
};
type Customer = {
  custname: string;
  age: number;
};

//! 第一种
type oneType<T, K> = K extends keyof T ? K : never; // 用于获取某种类型的所有键，keyof

type oneTypeResult = oneType<Customer, "custname">; // Customer包含custname 输出custname类型

//type oneType<Customer,  "custname"> =
//          "custname" extends "custname" |"age" ? "custname" : never

type oneTwoTypeResult = oneType<Customer, "xx">; // 输出never

type K1 = keyof Worker; // type K1 = "custname"

type oneTwoTypeResult2 = oneType<Customer, keyof Worker>; // 输出custname

type oneTwoTypeResult3 = oneType<Customer, "custname" | "xx">; // custname

//! 第二种
type twoType<T, K> = K extends keyof T ? T[K] : never;
type twoTypeResult = twoType<Customer, "age">; // 输出Custromer[age]基本类型number

// ! 第三种 keyof any
type threeType<K> = K extends keyof any ? K : never;

let count: number = 3;
type threeResultType = threeType<number>; // number

let stringName: string = "abc";
type threeResultType2 = threeType<typeof stringName>; // string

type threeResultType3 = threeType<3>; // 3 直接返回了值类型
let studSymid: symbol = Symbol["stuid"];
type symType = typeof studSymid; //symbol
type threeResultType4 = threeType<symbol>; // symbol

// ! 第四种
type Record<K extends keyof any, T> = {
  [P in "username" | "age"]: T;
};

//type resultRecord = {
//   age: Customer;
//   username: Customer;
// }
// 把联合类型跟后面的T(Customer)组合起起来了
type resultRecord = Record<string, Customer>;

// [P in string]可以代表任意一个字符串的可索引类型
// type Record2<K extends keyof any, T> = {
//   [P in string]: T;
// };
// 用 K 进行泛型约束
type Record2<K extends keyof any, T> = {
  [P in K]: T;
};
type resultRecord2 = Record2<string, Customer>;

let obj: resultRecord2 = {
  username: { custname: "www", age: 1},
  sername: { custname: "www", age: 1},
};

type resultRecord3 = Record2<number, Customer>;

// [x: number] 也可以代表数组里面的索引
let objarray: resultRecord3 = [{ custname: "wangwu", age: 23 },
{ custname: "lisi", age: 33}]


//? object 和 Map 和 Record 区别
/**
 type Record<K extends keyof any, T> = {
  [P in K]: T
}
 */

export {};
